package com.jhf.youke.base.app.executor;

import com.jhf.youke.base.domain.converter.UserConverter;
import com.jhf.youke.base.domain.event.UserEvent;
import com.jhf.youke.base.domain.model.Do.AuditDo;
import com.jhf.youke.base.domain.model.Do.UserDo;
import com.jhf.youke.base.domain.model.dto.RegisterCustomerDto;
import com.jhf.youke.base.domain.model.dto.RegisterRegimentalCommanderDto;
import com.jhf.youke.base.domain.model.dto.UserDto;
import com.jhf.youke.base.domain.model.po.UserPo;
import com.jhf.youke.base.domain.model.vo.UserVo;
import com.jhf.youke.base.domain.service.*;
import com.jhf.youke.core.ddd.BaseEvent;
import com.jhf.youke.core.entity.Pagination;
import com.jhf.youke.core.entity.User;
import com.jhf.youke.core.utils.CacheUtils;
import com.jhf.youke.core.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author RHJ
 * **/
@Slf4j
@Service
public class UserAppService {

    @Resource
    private UserService userService;

    @Resource
    private UserConverter userConverter;

    @Resource
    private RoleService roleService;

    @Resource
    private UserRoleService userRoleService;

    @Resource
    private CompanyService companyService;

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private AuditService auditService;

    public boolean update(UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        //更新角色
        userRoleService.updateRoleIdsByUserId(dto.getRoleIds(), dto.getId(), true);
        Map<String, Long> data = companyService.getDeptIdAndCompanyId(dto.getCompanyId());
        userDo.setCompanyId(data.get("companyId"));
        userDo.setRootId(data.get("rootId"));
        userDo.setDeptId(data.get("deptId"));
        return userService.update(userDo);
    }

    public boolean delete(UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.delete(userDo);
    }


    public boolean insert(UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        Map<String, Long> data = companyService.getDeptIdAndCompanyId(dto.getCompanyId());
        userDo.setRootId(data.get("rootId"));
        userDo.setCompanyId(data.get("companyId"));
        userDo.setDeptId(data.get("deptId"));
        UserPo po = userService.save(userDo);
        //更新角色
        userRoleService.updateRoleIdsByUserId(dto.getRoleIds(), po.getId(), false);
        return true;
    }

    public Optional<UserVo> findById(Long id) {
        Optional<UserVo> vo = userService.findById(id);
        vo.get().setRoleIds(userRoleService.getRoleIdsByUserId(id));
        return vo;
    }

    public boolean remove(Long id) {
        return userService.remove(id);
    }

    public boolean removeBatch(List<Long> idList) {
        return userService.removeBatch(idList);
    }

    public List<UserVo> findAllMatching(UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.findAllMatching(userDo);
    }

    /**
    * @Description:  设置单位权限示例，根据用户所在权限，自动查询本人单位及下属单位
    * @Param: [dto, token]
    * @return: Pagination<UserVo>
    * @Author: RHJ
    * @Date: 2022/11/7
    */
    public Pagination<UserVo> selectPage(UserDto dto, String token) {
        User user = CacheUtils.getUser(token);
        dto.setCompanyIds(user.getCompanyIds());
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.selectPage(userDo);
    }

    public boolean addRoles(UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.addRoles(userDo);
    }

    /**
     * 登录用户修改自己的信息
     *
     * @param userId
     * @param dto
     */
    public Boolean updateInfoByUserId(Long userId, UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.updateInfoByUserId(userId, userDo);
    }

    /**
     * 登录用户修改自己的密码
     *
     * @param userId
     * @param dto
     * @return
     */
    public Boolean updatePasswordByUserId(Long userId, UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.updatePasswordByUserId(userId, userDo);
    }

    public Boolean resetPassword(UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.resetPassword(userDo);
    }

    public Boolean updateStatus(UserDto dto) {
        UserDo userDo = userConverter.dto2Do(dto);
        return userService.updateStatus(userDo);
    }


    public Boolean registerRegimentalCommander(RegisterRegimentalCommanderDto dto) {

        // 邀请人id，团购名称[暂未]，用户名，姓名，手机号码，密码，小程序openId
        UserDo userDo = userService.registerRegimentalCommander(dto);
        // 保存团长审核记录
        auditService.saveRegimentalCommander(new AuditDo(userDo), dto.getReferrer());
        UserEvent event = new UserEvent(this, BaseEvent.EVENT_APPLICATION,"createSagaConsume",
                userDo.sagaMsgForCreateRegimentalCommander(dto.getReferrer()));
        applicationContext.publishEvent(event);

        return userDo.getId() > 0 ;
    }


    public Boolean registerCustomer(RegisterCustomerDto dto) {
        UserDo userDo = userService.registerCustomer(dto);

        UserEvent event = new UserEvent(this, BaseEvent.EVENT_APPLICATION,"createSagaConsume",
                userDo.sagaMsgForCreateCustomer(dto.getSaleMan()));
        applicationContext.publishEvent(event);

        return userDo.getId() > 0 ;
    }

    public void test() {
        String key ="1000";
        String requestId = "500";
        Boolean res = false;
        try {
            res = CacheUtils.lock(key, requestId, 5000);
            System.out.println("get lock:" + res);
            if(res){
                System.out.println(DateUtils.getCurrentDateStr() + " "  + Thread.currentThread().getName());
                Thread.sleep(2000);
            }

        }catch (Exception e){

        }finally {

            if(res == true){
                System.out.println("finally release lock");
                CacheUtils.release(key, requestId);
            }

        }

    }
}

